#include <iostream>
#include <string>
#include <mutex>  // 互斥锁
#include <condition_variable> // 条件变量
#include <thread>
#include <fstream>  // 文件操作
#include <atomic> // 原子操作
#include <sstream> // 字符串流
#include <vector>
#include <stdexcept> // 异常处理
#include <queue>
#include <chrono>       // 添加这个
#include <ctime>        // 添加这个
#include <iomanip>      // 添加这个

// 辅助函数，将单个参数转换为字符串
template<typename T>
std::string to_string_helper(T&& arg){
  std::ostringstream oss; //字符串流对象
  oss << std::forward<T>(arg);
  return oss.str();
}
// 时间函数
std::string getCurrentTime() {
  auto now = std::chrono::system_clock::now();
  std::time_t now_time = std::chrono::system_clock::to_time_t(now);
  char buffer[100];
  std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", std::localtime(&now_time));
  return std::string(buffer);
}

enum class LogLevel { INFO, DEBUG, ERROR };

// 线程安全的日志队列
class LogQueue {
public:
    void push(const std::string& msg) {
      std::lock_guard<std::mutex> lock(mutex_);
      queue_.push(msg);
      cond_var_.notify_one();
    }

    bool pop(std::string& msg) {
      std::unique_lock<std::mutex> lock(mutex_);
      while (queue_.empty() && !is_shutdown_) {
        cond_var_.wait(lock);
      }
      if (is_shutdown_ && queue_.empty()) {
        return false;
      }
      msg = queue_.front();
      queue_.pop();
      return true;
    }

    void shutdown() {
      std::lock_guard<std::mutex> lock(mutex_);
      is_shutdown_ = true;
      cond_var_.notify_all();
    }
private:
  std::queue<std::string> queue_;
  std::mutex mutex_;
  std::condition_variable cond_var_;
  bool is_shutdown_ = false;
};



// Logger类
class Logger {
public:
   Logger(const std::string& file_name):log_file_(file_name,std::ios::out | std::ios::app),exit_flag_(false) {
     if (!log_file_.is_open()) {
       throw std::runtime_error("无法打开日志文件");
     }
     worker_thread_ = std::thread(&Logger::processQueue, this);
   }

   ~Logger() {
     log_queue_.shutdown();
     if (worker_thread_.joinable()) {
       worker_thread_.join();
     }
     if (log_file_.is_open()) {
       log_file_.close();
     }
   }

   // 日志接口:支持带格式字符串的日志
   template <typename ... Args>
   void log(LogLevel level,const std::string& format, Args&&... args) {
     std::string level_str;
     switch (level)
     {
       case LogLevel::INFO:
         level_str = "[INFO] ";
         break;
       case LogLevel::DEBUG:
         level_str = "[DEBUG] ";
         break;
       case LogLevel::ERROR:
         level_str = "[ERROR] ";
         break;
     }
     log_queue_.push(level_str+ formatMessage(format, std::forward<Args>(args)...));
   }

private:
  LogQueue log_queue_;
  std::thread worker_thread_;
  std::ofstream log_file_;
  std::atomic<bool> exit_flag_;

  void processQueue() {
    std::string msg;
    while (log_queue_.pop(msg)) {
      log_file_ << msg << std::endl;
    }
  }

  // 使用模板折叠格式化日志消息，支持 "{}"占位符
  template <typename ... Args>
  std::string formatMessage(const std::string& format, Args ... args) {
    std::vector<std::string> args_string = {to_string_helper(std::forward<Args>(args))...};
    std::ostringstream oss;
    size_t arg_index = 0;
    size_t pos = 0;
    size_t placeholder = format.find("{}",pos);

    while (placeholder != std::string::npos) {

      oss << format.substr(pos, placeholder - pos);
      if (arg_index < args_string.size()) {
        oss << args_string[arg_index++];
      } else {
        // 没有足够的参数，保留"{}"
        oss << "{}";
      }

      pos = placeholder + 2; // 跳过 "{}"
      placeholder = format.find("{}",pos);


    }

    // 添加剩余的字符串
    oss << format.substr(pos);

    // 如果还有剩余的参数，按原方式拼接
    while (arg_index < args_string.size()) {
      oss << args_string[arg_index++];
    }
    return "[" + getCurrentTime() + "] " + oss.str();
  }
};


